package com.witframework.components.tag;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;

import com.witframework.components.SelectOptions;
import com.witframework.core.persistence.IBaseJdbcDao;
import com.witframework.util.BeanUtils;

public class SelectTag extends BodyTagSupport{
	private String name;//select的名称
	private String defaultValue;//缺省选中的值
	private String data;
	private String datatype;
	private String valueField;
	private String textField;
	private String filterName;
	private String filterValue;
	private String filters;
	private String className;
	private String onchange;
	private String onclick;
	private String options;
	private String readonly;
	static Log log = LogFactory.getLog(SelectTag.class);
	public final int doAfterBody() throws JspException{
		 BodyContent body = getBodyContent();
		 String s=body.getString();
		 if(StringUtils.isNotEmpty(s))
			 options = s.trim();
		 return SKIP_BODY;
	}
	@Override
	public int doEndTag() throws JspException {		 
	     HttpServletRequest request=(HttpServletRequest)pageContext.getRequest();
		
		StringBuffer html=new StringBuffer("<select name=\""+getName()+"\"");
		if(getClassName()!=null) html.append(" class=\""+getClassName()+"\"");
		if(getReadonly()!=null) html.append(" readonly=\"readonly\"");
		if(StringUtils.isNotEmpty(onchange)) html.append(" onchange=\""+onchange+"\"");
		if(StringUtils.isNotEmpty(onclick)) html.append(" onclick=\""+onclick+"\"");
		html.append(">\n");
		html.append(options);
		if(StringUtils.isEmpty(datatype)||datatype.equalsIgnoreCase("context")
				||datatype.equalsIgnoreCase("class")){
			Map<String,String> optMap;
			if(StringUtils.isEmpty(datatype)||datatype.equalsIgnoreCase("context"))
				optMap=(Map<String, String>)request.getAttribute(data);
			else
				optMap=((SelectOptions)BeanUtils.newInstance(data)).getOptionsMap();
			for(String text:optMap.keySet()){
				html.append("<option value=\""+optMap.get(text)+"\"");
				if(optMap.get(text).equals(defaultValue)) html.append(" selected ");
				html.append(">"+text);
				html.append("</option>\n");
			}
		}
		else{
			List optionItems=new ArrayList();			
			if(datatype.equalsIgnoreCase("table")||datatype.equalsIgnoreCase("sql")){
				IBaseJdbcDao dao=(IBaseJdbcDao)com.witframework.core.BeanFactory.getBean("baseJdbcDao");			
				StringBuffer query=new StringBuffer();
				if(datatype.equalsIgnoreCase("table")){				
					query.append("select "+valueField+" "+valueField+","+textField+" "+textField+" from "+data);				
					
					if(StringUtils.isNotEmpty(filters)){ 
						filters=StringUtils.replace(filters,"[","'");
						filters=StringUtils.replace(filters,"]","'");
						filters=StringUtils.replace(filters,"eq","=");
						filters=StringUtils.replace(filters,"gt",">");
						filters=StringUtils.replace(filters,"lt","<");
						filters=StringUtils.replace(filters,"ge",">=");
						filters=StringUtils.replace(filters,"le","<=");
						filters=StringUtils.replace(filters,"ne","!=");
						filters=StringUtils.replace(filters,".o/o.","%");				
					}				
					if(StringUtils.isNotEmpty(filters)){
						if(query.toString().toLowerCase().indexOf(" where ")<0){
							if(query.toString().toLowerCase().indexOf(" order ")<0)
								query.append(" where ").append(filters);
							else
								query.insert(query.toString().toLowerCase().indexOf(" order "), " where "+filters);
						}else{
							query.insert(query.toString().toLowerCase().indexOf(" where ")+7, filters+" and ");
						}
					}
				}else{				
					query.append(data);				
				}		
				optionItems=dao.queryForList(query.toString());			
			}
		
			for(Object item:optionItems){
				Object v,t;
				try {
					if(item instanceof Map){
						v=((Map)item).get(valueField);
						t=((Map)item).get(textField);
					}else{
						v = BeanUtils.getDeclaredProperty(item, valueField);
						t = BeanUtils.getDeclaredProperty(item, textField);
					}
				}  catch (Exception e) {
					v="";
					t="";
				}
				html.append("<option value=\""+v+"\"");
				if(((String)v).equals(defaultValue)) html.append(" selected ");
				html.append(">"+t);
				html.append("</option>\n");
			}		
		}			
		html.append("</select>\n");
		try {			
			pageContext.getOut().write(html.toString());
		} catch (IOException e) {
			throw new JspException("Print/Flush in LoadingTag tag error:" + e);
		}
		 return EVAL_PAGE;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;		
		try {
			this.name=(String) ExpressionEvaluatorManager.evaluate("name",name,String.class,this,pageContext);
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	public String getDefaultValue() {
		return defaultValue;
	}
	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
		try {
			this.defaultValue=(String) ExpressionEvaluatorManager.evaluate("defaultValue",defaultValue,String.class,this,pageContext);
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	
	public String getValueField() {
		return valueField;
	}
	public void setValueField(String valueField) {
		this.valueField = valueField;		
	}
	public String getTextField() {
		return textField;
	}
	public void setTextField(String textField) {
		this.textField = textField;		
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;		
	}
	public String getFilterName() {
		return filterName;
	}
	public void setFilterName(String filterName) {
		this.filterName = filterName;		
	}
	public String getFilterValue() {
		return filterValue;
	}
	public void setFilterValue(String filterValue) {
		this.filterValue = filterValue;		
		try {
			this.filterValue=(String) ExpressionEvaluatorManager.evaluate("filterValue",filterValue,String.class,this,pageContext);
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	public void setData(String data) {
		this.data = data;
	}
	public void setDatatype(String datatype) {
		this.datatype = datatype;
	}
	public void setFilters(String filters) {
		this.filters = filters;
	}
	public void setOnchange(String onchange) {
		this.onchange = onchange;
		try {
			this.onchange=(String) ExpressionEvaluatorManager.evaluate("onchange",onchange,String.class,this,pageContext);
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	public void setOnclick(String onclick) {
		this.onclick = onclick;
		try {
			this.onclick=(String) ExpressionEvaluatorManager.evaluate("onclick",onclick,String.class,this,pageContext);
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	public void setReadonly(String readonly) {		
		this.readonly = readonly;
		try {
			this.readonly=(String) ExpressionEvaluatorManager.evaluate("readonly",readonly,String.class,this,pageContext);
		} catch (JspException e) {
			e.printStackTrace();
		}
	}
	public String getReadonly() {
		return readonly;
	}
}
